package com.dzh.dzhhub.service.impl;

import com.dzh.dzhhub.common.Result;
import com.dzh.dzhhub.dao.LoginDao;
import com.dzh.dzhhub.entity.Permission;
import com.dzh.dzhhub.entity.User;
import com.dzh.dzhhub.service.LoginService;
import com.dzh.dzhhub.service.PermissionService;
import com.dzh.dzhhub.util.JedisUtil;
import com.dzh.dzhhub.util.JwtUtils;
import com.dzh.dzhhub.util.constants.Constants;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;

import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author DZHooo
 * @version 1.0
 * @date 2021/11/16 9:55
 * @description: TODO
 */

@Service
@PropertySource("classpath:config.properties")
public class LoginServiceImpl implements LoginService {

    @Autowired
    private LoginDao loginDao;

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private LoginService loginService;

    /**
     * RefreshToken过期时间
     */
    @Value("${refreshTokenExpireTime}")
    private String refreshTokenExpireTime;

    @Override
    public Result authLogin(String username, String password, ServletResponse response) {
        //JwtFilter拦截不到/login，所以走这里创建的token是UsernamePasswordToken，subject.login(token)进入的是UserRealm.class
        //其他url 会被JwtFilter拦截，然后走executeLogin()方法，创建的是jwtToken，subject.login(token)加入JwtRealm.class

        //获取当前用户主体
//        Subject currentUser = SecurityUtils.getSubject();
//        String msg = null;
//        boolean loginSuccess = false;
        //将用户名和密码封装成UsernamePasswordToken对象
//        UsernamePasswordToken token = new UsernamePasswordToken(username,password);

//        try {
//            //调用自定义Realm中的验证方法
//            currentUser.login(token);
//            msg = "登录成功。";
//            loginSuccess = true;
//        } catch (LockedAccountException lae) { // 账号已被锁定
//            msg = "该账户已被锁定，如需解锁请联系管理员！";
//        } catch (UnknownAccountException uae) { // 账号不存在
//            msg = "用户名与密码不匹配，请检查后重新输入！";
//        } catch (IncorrectCredentialsException ice) { // 账号与密码不匹配
//            msg = "用户名与密码不匹配，请检查后重新输入！";
//        } catch (AuthenticationException e) { // 其他身份验证异常
//            msg = "登录异常，请联系管理员！";
//        }

        User user = loginService.getUser(username,password);
        if(user == null) {
            throw new UnknownAccountException();
        }

        // 清除可能存在的Shiro权限信息缓存
        if(JedisUtil.exists(Constants.PREFIX_SHIRO_CACHE + username)) {
            JedisUtil.delKey(Constants.PREFIX_SHIRO_CACHE + username);
        }
        // 设置RefreshToken，时间戳为当前时间戳，直接设置即可(不用先删后设，会覆盖已有的RefreshToken)
        String currentTimeMillis = String.valueOf(System.currentTimeMillis());
        JedisUtil.setObject(Constants.PREFIX_SHIRO_REFRESH_TOKEN + username,currentTimeMillis,Integer.parseInt(refreshTokenExpireTime));
        // 从Header中Authorization返回AccessToken，时间戳为当前时间戳
        String token = JwtUtils.sign(username,currentTimeMillis);
        //将签发的JWT token 设置到HttpServletResponse 的Header中
        ((HttpServletResponse)response).setHeader(JwtUtils.AUTH_HEADER,token);
        return Result.success();


//        if(loginSuccess) {
//            //若登录成功，签发JWT token
//            String jwtToken = JwtUtils.sign(username,JwtUtils.SECRET);
//            //将签发的JWT token 设置到HttpServletResponse 的Header中
//            ((HttpServletResponse)response).setHeader(JwtUtils.AUTH_HEADER,jwtToken);
//            return Result.success();
//        }else {
//            return Result.error("401",msg);
//        }
    }


    @Override
    public User getUser(String username, String password) {
        return loginDao.getUser(username,password);
    }

    @Override
    public Result getInfo() {
        Session session = SecurityUtils.getSubject().getSession();
        User userinfo = (User)session.getAttribute(Constants.SESSION_USER_INFO);
        if(userinfo == null) {
            return Result.error("401","SESSION_USER_INFO 为空！");
        }
        String userName = userinfo.getUserName();
        Permission userPermission = permissionService.getUserPermission(userName);
        session.setAttribute(Constants.SESSION_USER_PERMISSION,userPermission);
        return Result.success(userPermission);
    }

    @Override
    public Result logout(String username) {
        try {
            Subject currentUser = SecurityUtils.getSubject();
            currentUser.logout();
            JedisUtil.delKey(Constants.PREFIX_SHIRO_REFRESH_TOKEN + username);
            JedisUtil.delKey(Constants.PREFIX_SHIRO_CACHE + username);
        } catch (Exception e) {
        }
        return Result.success();
    }


}
